package ace.tool.generate.code.impl.resolver.ui.resolver;

import ace.tool.generate.code.impl.manager.common.EntityModelManager;
import ace.tool.generate.code.impl.resolver.ui.model.bo.UiProjectCommonInfo;
import ace.tool.generate.code.impl.resolver.ui.model.bo.UiViewListClassInfo;
import ace.tool.generate.code.impl.resolver.ui.model.bo.UiViewListFieldInfo;
import ace.tool.generate.code.impl.resolver.ui.model.bo.UiViewListModelInfo;
import ace.tool.generate.code.impl.resolver.ui.model.dto.UiClassFileInfo;
import ace.tool.generate.code.impl.service.model.input.GenerateInput;
import ace.tool.generate.code.impl.service.model.input.GenerateModelFieldInput;
import ace.tool.generate.code.impl.service.model.input.GenerateModelInput;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.apache.commons.text.WordUtils;

/**
 * @author caspar
 * @date 2023/11/17 10:34
 */
@RequiredArgsConstructor
public class UiViewListClassResolver {
  private final GenerateInput input;
  private final GenerateModelInput modelInput;
  private final UiProjectCommonInfo commonInfo;
  private final EntityModelManager entityModelManager = EntityModelManager.getInstance();

  public UiViewListClassInfo resolve() {

    String entityModelId = new EntityModelManager().getEntityModelId(input, modelInput);

    UiClassFileInfo classFileInfo =
        UiClassFileInfoResolver.builder()
            .className(modelInput.getName())
            .classNameSuffix(input.getUiViewListClassNameSuffix())
            // .classPackagePrefix(input.getUiResponseClassPackagePrefix())
            .classPackagePrefix("")
            .rootPackageFullName(
                "/ui/antd/pages/main/view"
                    + "/"
                    + commonInfo.getProjectModuleCodeName()
                    + "/"
                    + modelInput.getName()
                    + input.getUiViewListClassNameSuffix())
            .sourceCodeRootDir(commonInfo.getSrcDir())
            .fileNameSuffix(".tsx")
            .build()
            .resolve();

    return UiViewListClassInfo.builder()
        .info(classFileInfo)
        .entityModelId(entityModelId)
        .model(this.getModel(entityModelId, classFileInfo))
        .apiConfigPrefix(this.getApiConfigPrefix())
        .build();
  }

  private String getApiConfigPrefix() {
    return "apiConfig."
        + this.commonInfo.getProjectModuleCodeName()
        + "."
        + WordUtils.uncapitalize(this.modelInput.getName());
  }

  private UiViewListModelInfo getModel(String entityModelId, UiClassFileInfo info) {
    List<UiViewListFieldInfo> fields = this.getFields(entityModelId, info);
    return UiViewListModelInfo.builder()
        .remark(this.modelInput.getRemark())
        .fields(fields)
        .idField(fields.stream().filter(UiViewListFieldInfo::getIdFlag).findFirst().orElse(null))
        .build();
  }

  private List<UiViewListFieldInfo> getFields(String entityModelId, UiClassFileInfo info) {
    List<UiViewListFieldInfo> fields =
        modelInput.getFields().stream().map(p -> this.getField(p)).collect(Collectors.toList());

    if (this.isNeedAddDeleteFlag(fields)) {
      fields.add(this.getDefaultDeleteField());
    }
    if (input.getEnableCreateTimeField()) {
      fields.add(this.getDefaultCreateTimeField());
    }
    if (input.getEnableUpdateTimeField()) {
      fields.add(this.getDefaultUpdateTimeField());
    }
    if (input.getEnableRowVersionField()) {
      fields.add(this.getDefaultRowVersionField());
    }
    return fields;
  }

  private boolean isNeedAddDeleteFlag(List<UiViewListFieldInfo> fields) {
    boolean isExitsDeleteFlagField =
        fields.stream().anyMatch(p -> p.getName().equals(input.getDeleteFlagFieldName()));
    return input.getEnableDeleteFlagField() && !isExitsDeleteFlagField;
  }

  private UiViewListFieldInfo getDefaultRowVersionField() {
    return UiViewListFieldInfo.builder()
        .name(input.getRowVersionFieldName())
        .remark("版本号和乐观锁")
        .remarkNotes("")
        .type(this.getMapType(Long.class))
        .nullable(false)
        .idFlag(false)
        .build();
  }

  private UiViewListFieldInfo getDefaultUpdateTimeField() {
    return UiViewListFieldInfo.builder()
        .name(input.getUpdateTimeFieldName())
        .remark("更新时间")
        .remarkNotes("单位-毫秒")
        .type(this.getMapType(Long.class))
        .nullable(false)
        .idFlag(false)
        .build();
  }

  private UiViewListFieldInfo getDefaultCreateTimeField() {
    return UiViewListFieldInfo.builder()
        .name(input.getCreateTimeFieldName())
        .remark("创建时间")
        .remarkNotes("单位-毫秒")
        .type(this.getMapType(Long.class))
        .nullable(false)
        .idFlag(false)
        .build();
  }

  private UiViewListFieldInfo getDefaultDeleteField() {
    return UiViewListFieldInfo.builder()
        .name(input.getDeleteFlagFieldName())
        .remark("删除标识")
        .remarkNotes("0-未删除")
        .type(this.getMapType(Long.class))
        .nullable(false)
        .idFlag(false)
        .build();
  }

  private String getMapType(Class<?> cls) {
    return new UiTypeResolver(cls).resolve();
  }

  private UiViewListFieldInfo getField(GenerateModelFieldInput modelFieldInput) {

    String remarkNotes = this.entityModelManager.getModelFieldEnumRemarkNotes(modelFieldInput);
    String remark = modelFieldInput.getRemark();
    if (remark.equals("id")) {
      remark = "ID";
    }
    return UiViewListFieldInfo.builder()
        .name(modelFieldInput.getName())
        .remark(remark)
        .remarkNotes(remarkNotes)
        .type(this.getMapType(modelFieldInput.getType()))
        .nullable(modelFieldInput.getNullable())
        .idFlag(modelFieldInput.getIdFlag())
        .build();
  }
}
